# 顺序表：用面向对象的思想去完成！
"""
类 = 属性 + 方法
对象：类是对象的抽象，对象是类的具体体现（实例化）
"""


# 定义一个顺序表的类
class SeqList:
    # 在类的里面定义变量叫做成员属性，函数叫做成员方法
    # 定义一个初始化顺序表的方法
    def __init__(self, max):  # self就相当于js里面的this
        # max形参表示顺序表的最大空间容量，到时由对象去分配空间
        # 将传入的实参max赋值给self.max
        self.max = max
        # 定义属性存储个数
        self.index = 0
        # 定义一个名为data的列表，并且最大空间数max的空列表
        self.data = [
            None for _ in range(self.max)
        ]  # 一个参数：默认从0开始，到这个数的前一个结束
        # [0,1,2,3,4,5,6,7,8,9]

    # 定义向末尾插入元素的方法
    def append(self, value):
        # 在插入元素之前，必须判断顺序表是否已经达到最大空间
        if self.index == self.max:
            print("顺序表空间已经满了，不能再添加了！")
            return
        else:
            # 列表名[索引号]
            self.data[self.index] = value
            # 索引+1
            self.index += 1

    # 定义一个按下标查找某元素是否存在的方法
    def search(self, index):
        # 如果下标不合法，则提示出错
        # 如果待下标不在0-9之间，报错
        if index < 0 or index >= self.index:
            print("您要查找的下标不合法！")
            return
        else:
            print("查找成功，这个数是：", self.data[index])

    # 遍历打印出顺序表中的每个元素
    def travel(self):
        for i in range(0, self.index):
            print(
                self.data[i], end=" "
            )  # print()方法默认换行输出。。。   end = " "不换行

    # 自己完成：将下标为3的元素值修改为666
    # 定义修改指定下标位置上的元素
    def changeItem(
        self, index, value
    ):  # index表示待修改的下标位置  value要修改成为的数字
        # 如果下标不合法，则提示出错
        # 如果待下标不在0-9之间，报错
        if index < 0 or index >= self.index:
            print("您要修改的下标不合法！")
            return
        else:
            # 把value赋值给index下标上
            self.data[index] = value

    # 定义判断顺序表是否为空的方法：
    def isEmpty(self):
        # 如果表中元素的个数为0，为空
        # 返回值：真 空   假非空
        if self.index == 0:
            return True
            # True  False
        else:
            return False

    # 定义向顺序表中任意下标位置插入元素的方法
    # 测试：向下标3的位置插入元素777   0 1 2 777 666 4 5 6 7 8 9
    def insert(self, index, value):
        if index < 0 or index > self.index:  # 10个元素  11个元素   0-10
            print("您要修改的下标不合法！")
            return
        # 第二种情况：假设插入的位置，正好在末尾，调用append()
        if index == self.index:
            self.append(value)
            return
        # 第三种情况：插入的位置不在最后
        else:
            # data列表10个元素，现在插入1个，需要将列表空间长度+1
            self.data = self.data + [value]  # 增加列表空间长度
            for i in range(self.index, index, -1):  # 从右往左遍历
                # 让元素后移，留出空间存储新值
                self.data[i] = self.data[i - 1]
            # 再把value放空里面
            self.data[index] = value
            # 元素的个数增加1
            self.index += 1

    # 定义删除尾部元素
    def deleteRear(self):
        # 删除之前，判断顺序表是否为空
        if self.isEmpty() == True:
            print("表为空！禁止删除！")
            return
        else:
            # 直接让顺序表的个数减少1
            self.index -= 1

    # 定义顺序表的长度
    def length(self):
        return self.index

    # 删除指定下标位置的元素
    def deleteItem(self, index):
        # 检查下标是否合法
        if index < 0 or index >= self.index:
            print("您要删除的下标不合法！")
            return
            # 从index位置开始，逐个向前移动元素，覆盖index位置的元素
        for i in range(index, self.index):
            self.data[i] = self.data[i + 1]
            # 更新顺序表中元素的个数
        self.index -= 1


# 编写主函数，测试上面类方法
if __name__ == "__main__":
    # 格式：   对象名 = 类名()
    # 创建一个顺序表类型的对象，并分配最大空间为10
    seqlist = SeqList(10)
    # 向顺序表中插入十个元素
    for i in range(0, 10):
        # 调用插入元素的方法，传入实参i
        seqlist.append(i)
    print("这个顺序表中的元素是：")
    seqlist.travel()
    print()
    # 查找下标为5的元素是否存在
    seqlist.search(5)
    print("将下标为3的元素修改为666：")
    seqlist.changeItem(3, 666)  # 0 1 2 666 4 5 6 7 8 9
    seqlist.travel()
    print()
    if seqlist.isEmpty() == True:
        print("这个顺序表为空！")
    else:
        print("这个顺序表不为空！")
    print("向下标为3的位置插入元素777：")
    seqlist.insert(3, 777)
    seqlist.travel()
    print()
    print("删除尾元素：")
    seqlist.deleteRear()
    seqlist.travel()
    print()
    # 课后作业：
    # 1：求出顺序表的长度
    length = seqlist.length()
    print("顺序表的长度为：", length)
    # 2：实现删除指定下标位置的元素（测试：删除下标为5的元素  0 1 2 777 666 5 6 7 8）
    seqlist.travel()
    seqlist.deleteItem(5)
    print()
    seqlist.travel()
